PAGE_PORT           equ 0x01
DIGITAL_IO_PORT     equ 0xFF
SIO_REG             equ 0xDE
SIO_DATA            equ 0xDF

CF_BASE             equ 0x98	    ;BASE ADDRESS OF PRIMARY IDE CONTROLLER
CF_REG0	            equ	CF_BASE + 0	;DATA PORT
CF_REG1	            equ	CF_BASE + 1	;READ: ERROR CODE, WRITE: FEATURE
CF_REG2	            equ	CF_BASE + 2	;NUMBER OF SECTORS TO TRANSFER
CF_REG3	            equ	CF_BASE + 3	;SECTOR ADDRESS LBA 0 [0:7]
CF_REG4	            equ	CF_BASE + 4	;SECTOR ADDRESS LBA 1 [8:15]
CF_REG5	            equ	CF_BASE + 5	;SECTOR ADDRESS LBA 2 [16:23]
CF_REG6	            equ	CF_BASE + 6	;SECTOR ADDRESS LBA 3 [24:27 (LSB)]
CF_REG7	            equ	CF_BASE + 7	;READ: STATUS, WRITE: COMMAND

FDOS                equ 0xDC00
BIOS                equ 0xF200

    org     0x8000
    ld      sp, 0xFFFF
    ld      a,10101010b
    out     (DIGITAL_IO_PORT),a            ;light up the LED
    ld      a,0
    out     (PAGE_PORT),a                  ;set 64K ram mode

entry:
    ld hl, FDOS

cf_ready:
    call    cf_wait
    in      a,(CF_REG7)
    and     0x40                        ;mask out DRDY bit
    jp      z,cf_ready
    ld      a,20                        ;set number of sectors to transfer
    out     (CF_REG2),a
    ld      a,1                         ;LBA bits 0~7
    out     (CF_REG3),a
    ld      a,0                         ;LBA bits 8~15
    out     (CF_REG4),a
    ld      a,0                         ;LBA bits 16~23
    out     (CF_REG5),a
    ld      a,0x20			            ;read command
	out	    (CF_REG7),a
    call    cf_wait

cf_read:                                ;read sectors
    in      a,(CF_REG0)                 ;get data
    ld      (hl),a                      ;copy to memory
	inc	    hl
    in      a,(CF_REG7)			        ;check if data transfer is ready
	and	    0x08                        ;mask out DRQ bit
    jp      nz,cf_read                  ;read next
    in      a,(CF_REG7)			        ;check status
	and	    0x01                        ;mask out ERR bit
    jp      nz,cf_read_error            ;read error

cf_read_success:
    ld      hl, sucess_prompt_mesg
    call    acia_print
    jp      BIOS

cf_read_error:
    ld      hl, error_prompt_mesg
    call    acia_print
    halt

cf_wait:
    in      a,(CF_REG7)                 ;read status
    and     0x80                        ;mask out BSY bit
    jp      nz, cf_wait                 ;wait until BSY is cleared
    ret
;
; Print message to ACIA.
;
acia_print:
    ld      a,(hl)
    inc     hl
    or      a
    ret     z                           ;return if encountered 0
    ld      c,a

acia_print_wait:
    in      a, (SIO_REG)                ;wait until write is ready
    and     0x02                        ;mask out TDRE bit
    jp      z,acia_print_wait
    ld      a,c
    out     (SIO_DATA), a
    jp      acia_print

sucess_prompt_mesg:
    defb "Load CP/M 2.2...\n", 0

error_prompt_mesg:
    defb "Load CP/M 2.2 Error!\n", 0
